package com.china08.yxyapi.rabbitmq.listener;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.log4j.Logger;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import com.china08.yxyapi.config.RabbitConfig;
import com.china08.yxyapi.entity.mg.attendance.YxyStuAttendance;
import com.china08.yxyapi.repository.mg.attendance.YxyStuAttendanceRepository;
import com.china08.yxyapi.util.DateUtils;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;

/**
 * 学生考勤统计
 *
 */
@Component
@EnableRabbit
public class StuAttendanceStatisticsListener {

    private static final Logger LOG = Logger.getLogger(StuAttendanceStatisticsListener.class);

    @Autowired
    private YxyStuAttendanceRepository yxyStuAttendanceRepository;

    @Value(value = "${yx.rest.api.yx.path}")
    private String yxyApiYxUrl;

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 根据学校ID 统计此学校的学生签到,
     * 
     * 参数中 schoolIdAndDay , map中key 为schoolId value:为日期 20170411 @throws
     */
    @RabbitListener(queues = RabbitConfig.YW_STU_ATTENDANCE_STATISTICS)
    private void attendanceStatistics(HashMap<String, Integer> schoolIdAndDay) {

        Set<String> schoolIds = schoolIdAndDay.keySet();
        // schoolId 虽然为 Set 但是只有一条
        for (String schoolId : schoolIds) {
            Integer day = schoolIdAndDay.get(schoolId);
            if (yxyStuAttendanceRepository.findTopByDayDateAndSchoolId(day, schoolId) == null) {
                // 一条记录都没有,不需要统计
                LOG.info("day: " + day + " schoolID: " + schoolId + " is not any students sign in ! ");
                return;
            }

            try {
                ResponseEntity<List<StuRespModel>> reList = restTemplate.exchange(
                        yxyApiYxUrl + "/comm/studentofschool/schoolId/" + schoolId, HttpMethod.GET, null,
                        new ParameterizedTypeReference<List<StuRespModel>>() {
                        });
                if (reList != null && reList.getBody() != null && reList.getBody().size() > 0) {

                    // 获取昨日学校学生签到的学生id 集合名stuAttendanceIdList
                    List<YxyStuAttendance> stuList = yxyStuAttendanceRepository.findByDayDateAndSchoolId(day, schoolId);
                    List<String> stuAttendanceIdList = new ArrayList<String>();
                    for (YxyStuAttendance yxyStuAttendance : stuList) {
                        stuAttendanceIdList.add(yxyStuAttendance.getSchoolId());
                    }

                    // 组装全校学生的idmap 名stuIdMap
                    Map<String, StuRespModel> stuIdMap = new HashMap<String, StuRespModel>();
                    List<StuRespModel> rates = reList.getBody();
                    for (StuRespModel stuRespModel : rates) {
                        stuIdMap.put(stuRespModel.getId(), stuRespModel);
                    }

                    // 筛选并获得未签到的学生id
                    for (String stuAttendanceId : stuAttendanceIdList) {
                        stuIdMap.remove(stuAttendanceId);
                    }

                    // 遍历map剩余数据 并把未签到学生录入新的签到数据 （状态：未签到）
                    for (Entry<String, StuRespModel> entry : stuIdMap.entrySet()) {
                        YxyStuAttendance yxyStuAttendance = new YxyStuAttendance();
                        yxyStuAttendance.setId(entry.getValue().getId() + "_" + DateUtils.formatStrDate4(day));
                        yxyStuAttendance.setStudentId(entry.getValue().getId());
                        yxyStuAttendance.setStudentName(entry.getValue().getName());
                        yxyStuAttendance.setAvatar(entry.getValue().getFaceImg());
                        yxyStuAttendance.setStudentNo(Long.valueOf(entry.getValue().getStudentNo()));
                        yxyStuAttendance.setClassId(entry.getValue().getOwnerClassId());
                        yxyStuAttendance.setClassName(entry.getValue().getClassNick());
                        yxyStuAttendance.setSchoolId(schoolId);
                        yxyStuAttendance.setSchoolName(entry.getValue().getSchoolNick());
                        yxyStuAttendance.setSignOutStatus(0);
                        yxyStuAttendance.setSignInStatus(0);
                        yxyStuAttendance.setInspection("未晨检");
                        yxyStuAttendance.setSignClass(0);
                        yxyStuAttendance.setDayDate(day);
                        yxyStuAttendance.setMonthDate(Integer.parseInt(String.valueOf(day.toString().substring(0, 6))));
                        yxyStuAttendance.setYearDate(
                                Integer.parseInt(String.valueOf(String.valueOf(day.toString().substring(0, 4)))));
                        yxyStuAttendanceRepository.save(yxyStuAttendance);
                    }
                } else {
                    LOG.info("schoolId: " + schoolId + " is not student information! ");
                }
            } catch (RestClientException e) {
                // TODO Auto-generated catch block
                LOG.error("RestClientException: yxyApiYxUrl  /api_yx/comm/studentofschool/schoolId/");
            } catch (ParseException e) {
                LOG.error("formatStrDate4: day is not yyyyMMdd");
            }
        }
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class StuRespModel {
        @JsonCreator
        public StuRespModel(@JsonProperty("name") String name, @JsonProperty("ownerClassId") String ownerClassId,
                @JsonProperty("classNick") String classNick, @JsonProperty("faceImg") String faceImg,
                @JsonProperty("studentNo") String studentNo, @JsonProperty("schoolNick") String schoolNick,
                @JsonProperty("id") String id) {
            super();

            this.id = id;
            this.name = name;
            this.ownerClassId = ownerClassId;
            this.classNick = classNick;
            this.faceImg = faceImg;
            this.studentNo = studentNo;
            this.schoolNick = schoolNick;
        }

        // 学生id
        private String id;
        // 学生姓名
        private String name;
        // 所属班级
        private String ownerClassId;
        // 班级名称
        private String classNick;
        // 头像
        private String faceImg;
        // 学号
        private String studentNo;
        // 学校名称
        private String schoolNick;

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getOwnerClassId() {
            return ownerClassId;
        }

        public void setOwnerClassId(String ownerClassId) {
            this.ownerClassId = ownerClassId;
        }

        public String getClassNick() {
            return classNick;
        }

        public void setClassNick(String classNick) {
            this.classNick = classNick;
        }

        public String getFaceImg() {
            return faceImg;
        }

        public void setFaceImg(String faceImg) {
            this.faceImg = faceImg;
        }

        public String getStudentNo() {
            return studentNo;
        }

        public void setStudentNo(String studentNo) {
            this.studentNo = studentNo;
        }

        public String getSchoolNick() {
            return schoolNick;
        }

        public void setSchoolNick(String schoolNick) {
            this.schoolNick = schoolNick;
        }

    }

}
